import 'dart:io';
import 'dart:ui';

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_svg/flutter_svg.dart';

enum CommonImageType { asset, network, file, cachedNetwork }

/// 支持svg和其他图片格式
class CommonImage extends StatelessWidget {
  final String uri;
  final double? width;
  final double? height;
  final BoxFit fit;
  final Color? color;
  final int? cacheWidth;
  final int? cacheHeight;
  final CommonImageType type;
  final PlaceholderWidgetBuilder? placeholder;
  final LoadingErrorWidgetBuilder? errorWidget;
  final String? package;

  const CommonImage.asset(
    this.uri, {
    super.key,
    this.width,
    this.height,
    this.fit = BoxFit.cover,
    this.color,
    this.cacheWidth,
    this.cacheHeight,
    this.placeholder,
    this.errorWidget,
    this.package,
  }) : type = CommonImageType.asset;

  const CommonImage.file(
    this.uri, {
    Key? key,
    this.width,
    this.height,
    this.fit = BoxFit.cover,
    this.color,
    this.cacheWidth,
    this.cacheHeight,
    this.placeholder,
    this.errorWidget,
  })  : type = CommonImageType.file,
        package = null,
        super(key: key);

  const CommonImage.network(
    this.uri, {
    Key? key,
    this.width,
    this.height,
    this.fit = BoxFit.cover,
    this.color,
    this.cacheWidth,
    this.cacheHeight,
    this.placeholder,
    this.errorWidget,
  })  : type = CommonImageType.network,
        package = null,
        super(key: key);

  const CommonImage.cachedNetwork(
    this.uri, {
    Key? key,
    this.width,
    this.height,
    this.fit = BoxFit.cover,
    this.color,
    this.cacheWidth,
    this.cacheHeight,
    this.placeholder,
    this.errorWidget,
  })  : type = CommonImageType.cachedNetwork,
        package = null,
        super(key: key);

  /// 低性能设备建议调低此数值,为空则使用设备的devicePixelRatio
  static double? imagePixelRatio;

  @override
  Widget build(BuildContext context) {
    switch (type) {
      case CommonImageType.asset:
        return uri.endsWith('svg')
            ? SvgPicture.asset(
                uri,
                width: width,
                height: height,
                fit: fit,
                colorFilter: color == null
                    ? null
                    : ColorFilter.mode(color!, BlendMode.srcIn),
                package: package,
              )
            : Image.asset(
                uri,
                width: width,
                height: height,
                fit: fit,
                color: color,
                cacheWidth: memCacheWidth,
                cacheHeight: memCacheHeight,
                package: package,
              );
      case CommonImageType.network:
        return uri.endsWith('svg')
            ? SvgPicture.network(
                uri,
                width: width,
                height: height,
                fit: fit,
                colorFilter: color == null
                    ? null
                    : ColorFilter.mode(color!, BlendMode.srcIn),
              )
            : Image.network(
                uri,
                width: width,
                height: height,
                fit: fit,
                color: color,
                cacheWidth: memCacheWidth,
                cacheHeight: memCacheHeight,
              );
      case CommonImageType.file:
        return uri.endsWith('svg')
            ? SvgPicture.file(
                File(uri),
                width: width,
                height: height,
                fit: fit,
                colorFilter: color == null
                    ? null
                    : ColorFilter.mode(color!, BlendMode.srcIn),
              )
            : Image.file(
                File(uri),
                width: width,
                height: height,
                fit: fit,
                color: color,
                cacheWidth: memCacheWidth,
                cacheHeight: memCacheHeight,
              );
      case CommonImageType.cachedNetwork:
        return uri.endsWith('svg')
            ? SvgPicture.network(
                uri,
                width: width,
                height: height,
                fit: fit,
                colorFilter: color == null
                    ? null
                    : ColorFilter.mode(color!, BlendMode.srcIn),
              )
            : CachedNetworkImage(
                imageUrl: uri,
                width: width,
                height: height,
                fit: fit,
                color: color,
                placeholder: placeholder,
                errorWidget: errorWidget,
                memCacheWidth: memCacheWidth,
                memCacheHeight: memCacheHeight,
              );
    }
  }

  int? get memCacheWidth =>
      cacheWidth ?? (width == null ? null : (width! * pixelRatio).toInt());

  int? get memCacheHeight =>
      cacheHeight ?? (height == null ? null : (height! * pixelRatio).toInt());

  static double get pixelRatio =>
      imagePixelRatio ??
      PlatformDispatcher.instance.views.first.devicePixelRatio;

  static int cacheSize(double size) => (size * pixelRatio).toInt();
}
